package edu.lehigh.cse.ale;

import org.andengine.engine.options.ScreenOrientation;
import org.andengine.entity.primitive.Rectangle;
import org.andengine.entity.scene.IOnSceneTouchListener;
import org.andengine.entity.scene.Scene;
import org.andengine.entity.text.Text;
import org.andengine.entity.text.TextOptions;
import org.andengine.input.touch.TouchEvent;
import org.andengine.opengl.font.Font;
import org.andengine.util.HorizontalAlign;

import android.view.MotionEvent;

public class Chooser
{
    /**
     * Track if there has been a screen down press on the menu chooser
     */
    private static boolean _downpress;

    /**
     * Create the level chooser
     * 
     * Note that portrait mode won't look good, and that the control buttons are invisible and a bit odd
     * 
     * @param font The font to use
     * 
     * @return the level chooser scene, so that it can be drawn
     */
    static Scene draw(Font font)
    {
        _downpress = false;
        if (Level._music != null) {
            if (Level._music.isPlaying())
                Level._music.pause();
            Level._music = null;
        }
        Scene s = new Scene();
        ALE.reinitCamera();

        // figure out if we are portrait or landscape mode, so we can place
        // things accordingly
        boolean landscape = Configuration.getCameraOrientation() == ScreenOrientation.LANDSCAPE_FIXED;
        int cw = Configuration.getCameraWidth();

        // bound the scroll behavior of the chooser
        int minY = 0;
        int maxY = 0;

        // secret button for unlocking
        if (Configuration.isDeveloperOverride()) {
            // Draw a bounding rectangle
            Rectangle r = new Rectangle(50, -200, 50, 50, ALE._self.getVertexBufferObjectManager());
            r.setColor(0, 0, 1);
            s.attachChild(r);
            Rectangle r2 = new Rectangle(52, -198, 46, 46, ALE._self.getVertexBufferObjectManager())
            {
                // When this _sprite is pressed, we unlock the level
                @Override
                public boolean onAreaTouched(TouchEvent e, float x, float y)
                {
                    MenuManager._unlocklevel = Configuration.getNumLevels();
                    MenuManager.saveUnlocked();
                    return true;
                }
            };
            r2.setColor(0, 0, 0);
            s.attachChild(r2);
            s.registerTouchArea(r2);

            // draw the level number
            Text t = new Text(50, -200, font, "X", new TextOptions(HorizontalAlign.CENTER),
                    ALE._self.getVertexBufferObjectManager());
            int h = (int) t.getHeight();
            int w = (int) t.getWidth();
            t.setPosition(50 + 50 / 2 - w / 2, -200 + 50 / 2 - h / 2);
            s.attachChild(t);

            minY = -200;
        }

        // draw some reasonably large buttons for the levels
        int bWidth = 60;
        int bHeight = 60;
        int cols = landscape ? 5 : 4;
        int hGutter = (cw - (cols * bWidth)) / (cols + 1);
        int vGutter = 15;
        int cur_x = hGutter;
        int cur_y = -bHeight;
        // reduce by one column, so we have room for sliders
        cols--;
        for (int i = 0; i < Configuration.getNumLevels(); ++i) {
            if (i % cols == 0) {
                cur_y = cur_y + bHeight + vGutter;
                cur_x = hGutter;
            }
            // Draw a bounding rectangle
            Rectangle r = new Rectangle(cur_x, cur_y, bWidth, bHeight, ALE._self.getVertexBufferObjectManager());
            r.setColor(0, 0, 1);
            s.attachChild(r);
            // for unlocked levels, draw an inner, touchable rectangle
            final int level = (i + 1);
            if (level <= MenuManager._unlocklevel) {
                Rectangle r2 = new Rectangle(cur_x + 2, cur_y + 2, bWidth - 4, bHeight - 4,
                        ALE._self.getVertexBufferObjectManager())
                {
                    // When this _sprite is pressed, we change the level and draw it
                    @Override
                    public boolean onAreaTouched(TouchEvent e, float x, float y)
                    {
                        if (e.getAction() != TouchEvent.ACTION_DOWN)
                            return false;
                        // change modes
                        MenuManager._mode = MenuManager.Modes.PLAY;
                        // now draw the chooser screen
                        ALE._self.getEngine().clearUpdateHandlers();
                        MenuManager._currLevel = level;
                        ALE._self.configureLevel(level);
                        ALE._self.getEngine().setScene(Level._current);
                        if (Level._music != null)
                            Level._music.play();

                        // NB: we return true because we are acting on account
                        // of the
                        // touch, so we don't want to propagate the touch to an
                        // underlying entity
                        return true;
                    }
                };
                r2.setColor(0, 0, 0);
                s.attachChild(r2);
                s.registerTouchArea(r2);
            }

            // draw the level number
            Text t = new Text(cur_x, cur_y, font, "" + level, new TextOptions(HorizontalAlign.CENTER),
                    ALE._self.getVertexBufferObjectManager());
            int h = (int) t.getHeight();
            int w = (int) t.getWidth();
            t.setPosition(cur_x + bWidth / 2 - w / 2, cur_y + bHeight / 2 - h / 2);
            s.attachChild(t);

            // for locked levels, cover the number with a semi-transparent
            // rectangle to gray it out
            if (level > MenuManager._unlocklevel) {
                Rectangle r2 = new Rectangle(cur_x + 2, cur_y + 2, bWidth - 4, bHeight - 4,
                        ALE._self.getVertexBufferObjectManager());
                r2.setColor(0, 0, 0);
                r2.setAlpha(0.5f);
                s.attachChild(r2);
                s.registerTouchArea(r2);
            }

            cur_x = cur_x + bWidth + hGutter;
            maxY = cur_y + 60;
        }

        // make the screen scrollable...
        final float max_y = maxY;
        final float min_y = minY;
        s.setOnSceneTouchListener(new IOnSceneTouchListener()
        {
            private float mTouchY;
            private float mTouchOffsetY;

            @Override
            public boolean onSceneTouchEvent(Scene PScene, TouchEvent pTouchEvent)
            {
                if (pTouchEvent.getAction() == MotionEvent.ACTION_DOWN) {
                    _downpress = true;
                    mTouchY = pTouchEvent.getMotionEvent().getY();
                }
                else if (_downpress && pTouchEvent.getAction() == MotionEvent.ACTION_MOVE) {
                    float newY = pTouchEvent.getMotionEvent().getY();
                    mTouchOffsetY = (newY - mTouchY);
                    float newScrollX = ALE._self._camera.getCenterX();
                    float newScrollY = ALE._self._camera.getCenterY() - mTouchOffsetY;
                    if (newScrollY < min_y)
                        newScrollY = min_y;
                    if (newScrollY > max_y)
                        newScrollY = max_y;

                    ALE._self._camera.setCenter(newScrollX, newScrollY);
                    mTouchY = newY;
                    return true;
                }
                else if (pTouchEvent.getAction() == MotionEvent.ACTION_UP) {
                    _downpress = false;
                }
                return false;
            }
        });

        return s;
    }

}